const argon2Lib = require('argon2');
const crypto = require('crypto');
const fs = require('fs');
const { execSync } = require('child_process'); // 用于运行二进制文件
const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout,
});
require('dotenv').config();

// 从 .env 文件加载加密数据
const ENCRYPTED_PRIVATE_KEY = process.env.ENCRYPTED_PRIVATE_KEY;
const NONCE = process.env.NONCE;
const AUTH_TAG = process.env.AUTH_TAG;
const salt = Buffer.from('fixedsalt12345678'); // 固定 salt，长度至少 16 字节

// 解密函数
async function decryptPrivateKey(password, encryptedData, nonce, authTag) {
  try {
    // 检查输入数据
    if (!encryptedData || !nonce || !authTag) {
      throw new Error('缺少必要的环境变量 (ENCRYPTED_PRIVATE_KEY, NONCE 或 AUTH_TAG)。');
    }

    console.log('开始解密...');
    console.log('加密数据:', encryptedData);
    console.log('Nonce:', nonce);
    console.log('Auth Tag:', authTag);

    // 使用 Argon2id 生成 AES-256 密钥
    const key = await argon2Lib.hash(password, {
      type: argon2Lib.argon2id,
      memoryCost: 2 ** 16,
      timeCost: 4,
      parallelism: 1,
      hashLength: 32,
      raw: true,
      salt: salt, // 显式指定 salt
    });
    console.log('生成的 AES-256 密钥 (hex):', key.toString('hex'));

    // 解密
    const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(nonce, 'hex'));
    decipher.setAuthTag(Buffer.from(authTag, 'hex'));
    let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
    decrypted += decipher.final('utf8');

    // console.log('解密的 Solana 私钥:', decrypted);
    return decrypted;
  } catch (error) {
    throw new Error(`解密失败: ${error.message}`);
  }
}

// 获取用户输入的密码（带重试机制）
async function getPasswordWithRetry(maxRetries = 3) {
  let retries = 0;
  while (retries < maxRetries) {
    const password = await new Promise((resolve) => {
      readline.question(`请输入解密密码 (尝试 ${retries + 1}/${maxRetries}): `, (pass) => {
        resolve(pass);
      });
    });
    try {
      const decrypted = await decryptPrivateKey(password, ENCRYPTED_PRIVATE_KEY, NONCE, AUTH_TAG);
      return { password, decrypted };
    } catch (error) {
      retries++;
      console.log(`解密失败: ${error.message}。剩余 ${maxRetries - retries} 次尝试。`);
      if (retries === maxRetries) {
        throw new Error('超过最大密码重试次数。');
      }
    }
  }
}

// 更新 config.toml 文件中的 private_key
function updateConfigTomlPrivateKey(newPrivateKey) {
  try {
    const configContent = fs.readFileSync('config.toml', 'utf-8');
    const lines = configContent.split('\n');
    let updatedContent = '';

    for (let line of lines) {
      if (line.trim().startsWith('private_key =')) {
        updatedContent += `private_key = "${newPrivateKey}"\n`;
      } else {
        updatedContent += line + '\n';
      }
    }

    fs.writeFileSync('config.toml', updatedContent.trim() + '\n');
    console.log(`config.toml 已更新: private_key 设置为 "${newPrivateKey || '(empty)'}"`);
  } catch (error) {
    throw new Error(`更新 config.toml 失败: ${error.message}`);
  }
}

// 主函数
async function main() {
  try {
    // 验证环境变量
    console.log('ENCRYPTED_PRIVATE_KEY:', ENCRYPTED_PRIVATE_KEY);
    console.log('NONCE:', NONCE);
    console.log('AUTH_TAG:', AUTH_TAG);

    // 获取用户输入的密码并解密
    const { decrypted: privateKey } = await getPasswordWithRetry();

    // 解密成功，输出私钥
    // console.log('解密成功！Solana 私钥:', privateKey);

    // 更新 config.toml 文件中的 private_key
    updateConfigTomlPrivateKey(privateKey);

    // 运行本地二进制文件 ./smb-onchain run config.toml
    console.log('运行 ../smb-onchain run config.toml...');
    execSync('../smb-onchain run config.toml', { stdio: 'inherit' });

    // 运行完成后，将 config.toml 中的 private_key 置为空
    updateConfigTomlPrivateKey('');

    // 关闭 readline
    readline.close();
  } catch (error) {
    console.error(`错误: ${error.message}`);
    readline.close();
  }
}

main().catch(console.error);